package dbops

import (
	"database/sql"
	"log"
	"strconv"
	"sync"

	"video_server/api/defs"
)

/*
定义为 internal的原因：
	1. 不是直接跟 handle 交互的，是跟 session交互的
	2. 此处存放所有与 session 交互的动作
*/

/*
dpops中的操作：
	1. 向session表中写入session
	2. 拿session信息
	3. list所有 session
	4. 生成一个session
*/

func InsertSession(sessionId string, ttl int64, username string) error {
	//将 ttl 转换成 string类型
	ttlstr := strconv.FormatInt(ttl, 10)
	stmtIns, err := dbConn.Prepare("INSERT INTO sessions (session_id,TTL,login_name) values(?,?,?)")
	if err != nil {
		return err
	}

	_, err = stmtIns.Exec(sessionId, ttlstr, username)
	if err != nil {
		return err
	}

	defer stmtIns.Close()

	return nil
}

// 找回 session
func RetrieveSession(sessionId string) (*defs.SimpleSession, error) {
	ss := &defs.SimpleSession{}
	stmtOut, err := dbConn.Prepare("SELECT TTL,login_name FROM  sessions WHERE session_id = ?")
	if err != nil {
		return nil, err
	}

	var ttl string
	var uname string
	err = stmtOut.QueryRow(sessionId).Scan(&ttl, &uname)
	if err != nil && err != sql.ErrNoRows {
		return nil, err
	}

	if res, err := strconv.ParseInt(ttl, 10, 64); err == nil {
		ss.TTL = res
		ss.Username = uname
	} else {
		return nil, err
	}
	defer stmtOut.Close()
	return ss, nil
}

func RetrieveAllSession() (*sync.Map, error) {
	m := &sync.Map{}

	stmtOut, err := dbConn.Prepare("SELECT * FROM sessions")

	rows, err := stmtOut.Query()
	if err != nil {
		return nil, err
	}
	for rows.Next() {
		var id string
		var ttlstr string
		var login_name string
		if err := rows.Scan(&id, &ttlstr, &login_name); err != nil {
			log.Printf("retrie sessions error:%s", err)
			break
		}
		if ttl, err := strconv.ParseInt(ttlstr, 10, 64); err == nil {
			ss := &defs.SimpleSession{
				Username: login_name,
				TTL:      ttl,
			}
			m.Store(id, ss)
			log.Printf(" session id: %s, ttl: %d", id, ss.TTL)
		}

	}

	return m, nil
}

func DeleteSession(sessionId string) error {
	stmtOut, err := dbConn.Prepare("DELETE FROM sessions where session_id=?")
	if err != nil {
		log.Printf("%s", err)
		return err
	}

	if _, err = stmtOut.Query(sessionId); err != nil {
		return err
	}

	return nil

}
